// stores/socket.js
import { defineStore } from 'pinia';
import { io } from '@hyoga/uni-socket.io';
import { SOCKET_SERVER_URL } from '@/config.js';
// import { h } from 'vue';

/**
 * Socket 连接状态枚举
 * - disconnected: 未连接
 * - connecting: 连接中
 * - connected: 已连接
 * - error: 连接错误
 */
const CONNECTION_STATES = {
  DISCONNECTED: 'disconnected',
  CONNECTING: 'connecting',
  CONNECTED: 'connected',
  ERROR: 'error'
};

/**
 * Socket 通信仓库
 * 负责管理全局唯一的 Socket 连接、房间数据及通信状态
 * 支持多房间切换、自动重连、事件监听等核心功能
 */
export const useSocketStore = defineStore('socket', {
  state: () => ({
    socket: null,                // Socket.IO 实例（全局唯一）
    currentRoomId: '',           // 当前活跃房间 ID
    currentUserId: '',           // 当前活跃用户 ID
    roomData: {},                // 按房间 ID 隔离存储的结构化数据   
    connectionState: CONNECTION_STATES.DISCONNECTED, // 连接状态
    error: null                  // 错误信息（连接失败时存储具体原因）
  }),

  actions: {
    /**
     * 初始化 Socket 连接并加入指定房间
     * 若已连接到目标房间则复用连接，否则创建新连接
     * @param {string} roomId - 目标房间 ID
     * @returns {Promise<void>} - 连接状态变更的 Promise
     */
    async connect(roomId) {
      // 已连接到目标房间，直接返回
      if (this.isConnectedToRoom(roomId)) {
		  console.log("已连接到此房间")
        return;
      }

      // 清理现有连接（切换房间或重连场景）
      if (this.socket) {
        this.disconnect();
		console.log("断开连接到此房间")
      }

      try {
        // 更新连接状态为"连接中"
        this.connectionState = CONNECTION_STATES.CONNECTING;
        this.currentRoomId = roomId;

        // 初始化房间数据结构（若不存在）
        this._initRoomData(roomId);

        // 获取当前用户 ID（从本地存储）
        const userId = this._getCurrentUserId();

        // 创建 Socket 连接
        this.socket = io(SOCKET_SERVER_URL, {
          query: {
            room_id: roomId,    // 房间标识
            user_id: userId     // 用户标识
          },
          transports: ['websocket'],  // 强制使用 WebSocket 协议
          reconnection: true,         // 启用自动重连
          reconnectionAttempts: 5,    // 最大重连次数
          reconnectionDelay: 1000,    // 重连间隔（毫秒）
          timeout: 5000             // 连接超时时间（毫秒）

        });
		console.log("socket：",this.socket)
        // 设置事件监听（核心业务逻辑）
        this._setupEventListeners();


      } catch (err) {
        // 连接失败处理
        this.connectionState = CONNECTION_STATES.ERROR;
        this.error = err.message || 'Socket 连接初始化失败';
        console.error('Socket 连接异常:', err);
      }
    },

    /**
     * 初始化房间数据结构
     * 确保房间数据存在默认字段，避免后续操作出现 undefined 错误
     * @param {string} roomId - 房间 ID
     */
    _initRoomData(roomId) {
      if (!this.roomData[roomId]) {
        this.roomData[roomId] = {
          members: {},       // 房间成员列表（key: 用户ID，value: 用户信息）
          history: [],       // 历史消息/操作记录
          gameState: null    ,// 游戏状态（如回合数、当前操作等）
		  //  新增结算状态（关键）
		  settlement: {
			currentRound: 0,       // 当前结算回合号
			submittedUsers: [],    // 已提交用户ID列表
			scores: {},            // 存储每个人的分数数据
			isCompleted: false     // 是否全部提交完成
		  }
    };
  }
},

    /**
     * 设置 Socket 事件监听
     * 统一管理系统级事件（连接/断开）和业务事件（成员变更/状态更新）
     */
    _setupEventListeners() {
      // 避免重复绑定事件（先移除现有监听）
      this.socket.offAny();

      // 系统事件：连接成功
      this.socket.on('connect', () => {
        this.connectionState = CONNECTION_STATES.CONNECTED;
        this.error = null; // 清除错误信息
		console.log("连接建立")
		
		// this.socket.emit('init_room', { room_id: this.currentRoomId});
		
        console.log(`Socket 已连接到房间: ${this.currentRoomId}`);
      });

      // 系统事件：连接断开
      this.socket.on('disconnect', (reason) => {
        this.connectionState = CONNECTION_STATES.DISCONNECTED;
        console.log(`Socket 断开连接（房间: ${this.currentRoomId}），原因:`, reason);
        // 被动断开时尝试重连（如网络波动）
        if (reason === 'io server disconnect') {
          this.socket.connect(); // 服务器主动断开，需手动重连
        }
      });

      // 系统事件：连接错误
      this.socket.on('connect_error', (err) => {
        this.connectionState = CONNECTION_STATES.ERROR;
        this.error = `连接失败: ${err.message}`;
        console.error('Socket 连接错误:', err);
      });
// ****************************************************************************************
      // 业务事件：房间成员初始化（首次加入房间时触发）
      this.socket.on('update_members', (data) => {
		// 1. 检查房间是否存在
        if (data.room_id !== this.currentRoomId) return;
		// 2. 更新数据
        this.roomData[data.room_id].members = data.members;
        console.log(`房间 ${data.room_id} 信息已更新，共 ${Object.keys(data.members).length} 人`);
      });
	  
	  // 业务事件：历史记录更新（如消息记录、操作日志）
	  this.socket.on('update_history', (data) => {	
		//解构赋值语法
	    const { room_id: roomId, history } = data;
		// 1. 检查房间是否存在
	    if (!this.roomData[roomId]) return;
	  	// 2. 更新房间的历史记录
	    this.roomData[roomId].history = history;
	    console.log(`房间 ${roomId} 历史记录更新，共 ${history.length} 条`);
	  });
	  
      // 业务事件：用户加入房间
      this.socket.on('user_joined', (data) => {
        const { room_id: roomId, user_id: userId, user_info: userInfo } = data;
        if (!this.roomData[roomId]) return;
			
        this.roomData[roomId].members[userId] = userInfo;
        console.log(`用户 ${userId} 加入房间 ${roomId}`);
      });

      // 业务事件：用户离开房间
      this.socket.on('user_left', (data) => {
        const { room_id: roomId, user_id: userId } = data;
        if (!this.roomData[roomId]?.members[userId]) return;

        delete this.roomData[roomId].members[userId];
        console.log(`用户 ${userId} 离开房间 ${roomId}`);
      });

      // 业务事件：游戏状态更新（如回合切换、分数变更等）
      this.socket.on('game_state_update', (data) => {
        const { room_id: roomId, state } = data;
        if (!this.roomData[roomId]) return;

        this.roomData[roomId].gameState = state;
        console.log(`房间 ${roomId} 游戏状态更新`);
      });
	  
	  
	  
	  
	  
	  
	  
	  //***************结算页业务事件*******************************
	  // 监听用户提交分数
	 //  this.socket.on('user_score_submitted', (data) => {
		// console.log("执行user_score_submitted前")
	 //    const { room_id: roomId, roundNumber, user_id, score, isWinner } = data;
		// console.log("执行user_score_submitted中data",data)
	 //    if (!this.roomData[roomId]) return;
	 //    // 只处理当前回合的结算
	 //    if (this.roomData[roomId].settlement.currentRound !== roundNumber) {
		// 	console.log("执行this.roomData[roomId].settlement.currentRound",this.roomData[roomId].settlement.currentRound)
		// 	console.log("执行roundNumber",roundNumber)
		// 	return;
		// }
	 //    // 更新分数数据
	 //    this.roomData[roomId].settlement.scores[user_id] = { score, isWinner };
	 //    // 记录已提交用户（去重）
	 //    if (!this.roomData[roomId].settlement.submittedUsers.includes(user_id)) {
	 //      this.roomData[roomId].settlement.submittedUsers.push(user_id);
	 //    }
		// console.log("执行user_score_submitted后")
	 //  });
	  
	  // 监听全部提交完成
	  this.socket.on('settlement_all_completed', (data) => {
	    const { room_id: roomId, roundNumber } = data;
	    if (this.roomData[roomId] && this.roomData[roomId].settlement.currentRound === roundNumber) {
	      this.roomData[roomId].settlement.isCompleted = true;
	    }
	  });
	  
	
    },

    /**
     * 离开当前房间（保留连接，仅发送离开通知）
     * 适用于临时切换页面但不关闭连接的场景
     */
    leaveRoom() {
      if (!this.socket || !this.currentRoomId) return;

      this.socket.emit('leave_room', {
        room_id: this.currentRoomId,
        user_id: this._getCurrentUserId()
      });

//       delete this.roomData[roomId]; // 释放内存

      console.log(`已发送离开房间 ${this.currentRoomId} 的请求`);
    },

    /**
     * 完全断开 Socket 连接
     * 适用于退出应用、切换账号等场景
     */
    disconnect() {
      if (!this.socket) return;

      // 先发送离开房间通知
      this.leaveRoom();

      // 断开连接并清理状态
      this.socket.disconnect();
      this.socket = null;
      this.connectionState = CONNECTION_STATES.DISCONNECTED;
      this.currentRoomId = '';
      this.error = null;

      console.log('Socket 连接已完全断开');
    },

    /**
     * 发送回合结算数据
     * 封装业务请求，支持回调处理
     * @param {object} data - 结算数据（如分数、操作结果等）
     * @returns {Promise<object>} - 服务器响应结果
     */
    submitSettlement(data) {
      return new Promise((resolve, reject) => {
        // 校验连接状态
        if (!this.socket || this.connectionState !== CONNECTION_STATES.CONNECTED) {
          reject(new Error('Socket 未连接，无法提交结算数据'));
          return;
        }

        // 补充必要参数（房间 ID 和用户 ID）
        const payload = {
          ...data,
          room_id: this.currentRoomId,
          user_id: this._getCurrentUserId()
        };

        // 发送请求并等待响应（使用回调模式）
        this.socket.emit('settle_round', payload, (response) => {
          if (response.success) {
            resolve(response.data);
          } else {
            reject(new Error(response.message || '结算提交失败'));
          }
        });
      });
    },

    /**
     * 注册自定义事件监听
     * 允许外部组件监听额外业务事件（如自定义消息）
     * @param {string} eventName - 事件名称
     * @param {Function} handler - 事件处理函数
     */
    on(eventName, handler) {
      if (this.socket && typeof handler === 'function') {
        this.socket.on(eventName, handler);
      }
    },

    /**
     * 移除自定义事件监听
     * 避免组件卸载后事件残留导致内存泄漏
     * @param {string} eventName - 事件名称
     * @param {Function} handler - 事件处理函数（需与注册时一致）
     */
    off(eventName, handler) {
      if (this.socket && typeof handler === 'function') {
        this.socket.off(eventName, handler);
      }
    },

    /**
     * 发送自定义事件数据
     * 封装 emit 方法，增加连接状态校验
     * @param {string} eventName - 事件名称
     * @param {object} data - 发送的数据
     */
    emit(eventName, data) {
      if (!this.socket || this.connectionState !== CONNECTION_STATES.CONNECTED) {
        console.warn('Socket 未连接，无法发送数据');
        return;
      }

      this.socket.emit(eventName, {
        ...data,
        room_id: this.currentRoomId, // 自动补充当前房间 ID
        // user_id: this._getCurrentUserId() // 自动补充当前用户 ID
      });
    },

    /**
     * 从本地存储获取当前用户 ID
     * 封装用户信息获取逻辑，避免重复代码
     * @returns {string} - 用户 ID（若不存在则返回空字符串）
     */
    _getCurrentUserId() {
      try {
        const userStr = uni.getStorageSync('user') || '{}';
        const user = JSON.parse(userStr);
        return user.userinfo?.userid || '';
      } catch (err) {
        console.error('解析用户信息失败:', err);
        return '';
      }
    }
  },






// // 长期不用的房间数据定时清理
// setInterval(() => {
//   Object.keys(this.roomData).forEach(roomId => {
//     if (Date.now() - this.roomData[roomId].lastActive > 30*60*1000) {
//       delete this.roomData[roomId];
//     }
//   });
// }, 5*60*1000);


  getters: {
    //获取当前房间的成员列表:返回成员字典（key: 用户ID，value: 用户信息）
    currentMembers(state) {
      return state.currentRoomId ? state.roomData[state.currentRoomId]?.members || {} : {};
    },

	//获取当前房间的游戏状态:返回游戏状态数据（如无则返回 null）
    currentGameState(state) {
      return state.currentRoomId ? state.roomData[state.currentRoomId]?.gameState || null : null;
    },

    //获取当前房间的历史记录:返回历史记录数组（如无则返回空数组）
    currentHistory(state) {
      return state.currentRoomId ? state.roomData[state.currentRoomId]?.history || [] : [];
    },

    /**
     * 检查是否已连接到指定房间
     * @param {string} roomId - 房间 ID
     * @returns {boolean} - 连接状态（已连接且房间匹配则返回 true）
     */
    isConnectedToRoom: (state) => (roomId) => {
      return state.currentRoomId === roomId 
        && state.connectionState === CONNECTION_STATES.CONNECTED;
    },

    /**
     * 检查当前是否处于连接中状态
     * @returns {boolean} - 连接中状态标识
     */
    isConnecting(state) {
      return state.connectionState === CONNECTION_STATES.CONNECTING;
    },

    /**
     * 检查是否存在连接错误
     * @returns {boolean} - 错误状态标识
     */
    hasError(state) {
      return state.connectionState === CONNECTION_STATES.ERROR;
    }
  }
});